#include "net.hpp"

void return_socket_addr(struct sockaddr_in& n_sock_addr, const string& n_host, int n_value){
    bzero(&n_sock_addr, sizeof(sockaddr_in));
    n_sock_addr.sin_family = AF_INET;
    n_sock_addr.sin_addr = INADDR_ANY;
    n_sock_addr.sin_port = htons(n_value);
}

sock_c::sock_c() :
	m_active(false),
	m_handle(-1),
    m_domain(PF_INET),
    m_type(stream_sock),
    m_protocol(IPPROTO_IP),
    m_block_mode(true)
{
}

sock_c::~sock_c(){
    close();
}

void sock_c::enable_block_mode(int n_handle, bool n_value){
    int flag = fcntl(n_handle, F_GETFL);

    if (n_value)
        flag &= ~O_NONBLOCK;
    else
        flag |= O_NONBLOCK;
        
    if (fcntl(n_handle, F_SETFL, flag) < 0)
        throw sock_c_exception(strerror(errno), __FILE__, __LINE__);
}

void sock_c::sig_active(bool n_sig){
    if (n_sig != m_active)
    {
        if (n_sig) open();
        else close();
    }
}

void sock_c::sig_domain(int n_sig){
    if (n_sig != m_domain){
        if (is_active()) close();
        m_domain = n_sig;
    }
}

void sock_c::sig_type(int n_sig){
    if (n_sig != m_type){
        if (is_active()) close();
        m_type = n_sig;
    }
}

void sock_c::sig_protocol(int n_sig){
    if (n_sig != m_protocol){
        if (is_active()) close();
        m_protocol = n_sig;
    }
}

void sock_c::sig_block_mode(bool n_sig){
    if (m_active)
        enable_block_mode(m_handle, n_sig);
    m_block_mode = n_sig;
}

void sock_c::sig_handle(int n_sig){
    if (n_sig != m_handle){
        if (is_active()) close();
        m_handle = n_sig;
        if (m_handle != -1) 
            m_active = true;
    }
}

void sock_c::open(){
    if (!m_active){
        try
        {
            int handle;
            handle = socket(m_domain, m_type, m_protocol);
            if (handle == -1)
                throw sock_c_exception(strerror(errno), __FILE__, __LINE__);
            m_active = (handle != -1);
            if (m_active){
                m_handle = handle;
                set_block_mode(m_block_mode);
            }
        }
        catch (sock_c_exception& e)
        {
            close(m_handle);
            m_handle = -1;
            m_active = false;
            throw e;
        }
    }
}

void sock_c::close(){
    if (m_active)
    {
        close(m_handle);
        m_handle = -1;
        m_active = false;
    }
}



crypto_stream_c::crypto_stream_c():
	m_ctx(0),
	m_ssl(0),
	m_meth(0){
		load_crypto_lib();
}
crypto_stream_c::~crypto_stream_c(){
	
}
void crypto_stream_c::load_crypto_lib(){
	SSL_load_error_strings();
	SSLeay_add_ssl_algorithms();
}
